package com.code2roc.jarmanage.util;

import org.apache.commons.io.input.ReversedLinesFileReader;

import java.io.*;
import java.nio.charset.Charset;
import java.nio.charset.StandardCharsets;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.attribute.BasicFileAttributes;
import java.time.Instant;
import java.time.ZoneId;
import java.time.format.DateTimeFormatter;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;

public class FileUtil {

    public static boolean delete(String fileName) {
        File file = new File(fileName);
        if (!file.exists()) {
            return false;
        } else {
            if (file.isFile())
                return deleteFile(fileName);
            else
                return deleteDirectory(fileName);
        }
    }

    public static boolean deleteFile(String fileName) {
        File file = new File(fileName);
        if (file.exists() && file.isFile()) {
            if (file.delete()) {
                return true;
            } else {
                return false;
            }
        } else {
            return false;
        }
    }

    public static boolean deleteDirectory(String dir) {
        if (!dir.endsWith(File.separator))
            dir = dir + File.separator;
        File dirFile = new File(dir);
        if ((!dirFile.exists()) || (!dirFile.isDirectory())) {
            return false;
        }
        boolean flag = true;
        File[] files = dirFile.listFiles();
        for (int i = 0; i < files.length; i++) {
            if (files[i].isFile()) {
                flag = deleteFile(files[i].getAbsolutePath());
                if (!flag)
                    break;
            } else if (files[i].isDirectory()) {
                flag = deleteDirectory(files[i].getAbsolutePath());
                if (!flag)
                    break;
            }
        }
        if (!flag) {
            return false;
        }
        if (dirFile.delete()) {
            return true;
        } else {
            return false;
        }
    }

    public static void initfloderPath(String floderName) {
        if (!StringUtil.isEmpty(floderName)) {
            File file = new File(floderName);
            if (!file.exists()) {
                file.mkdirs();
            }
        }
    }

    public static void uploadFile(byte[] file, String filePath) {
        try {
            FileOutputStream out = new FileOutputStream(filePath);
            out.write(file);
            out.flush();
            out.close();
        } catch (Exception e) {
            LogUtil.error(e);
        }
    }

    public static void copyFile(String sourceFilePath, String tagretFilePath) {
        try {
            File file = new File(tagretFilePath);
            if (file.exists()) {
                file.delete();
            }
            InputStream in = new FileInputStream(sourceFilePath);
            OutputStream out = new FileOutputStream(tagretFilePath);
            byte[] buffer = new byte[2048];
            int nBytes = 0;
            while ((nBytes = in.read(buffer)) > 0) {
                out.write(buffer, 0, nBytes);
            }
            out.flush();
            out.close();
            in.close();
        } catch (Exception e) {
            LogUtil.error(e);
        }
    }

    public static void copyFileFolder(String sourceFolderPath, String targetFolderPath) throws IOException {
        File file = new File(targetFolderPath);
        if (!file.exists()) {
            file.mkdirs();
        }
        copy(sourceFolderPath, targetFolderPath);
    }

    private static void copy(String f1, String f2) throws IOException {
        File file1 = new File(f1);
        File[] flist = file1.listFiles();
        for (File f : flist) {
            if (f.isFile()) {
                copyFile(f.getPath(), f2 + "/" + f.getName());
            } else if (f.isDirectory()) {
                copyFileFolder(f.getPath(), f2 + "/" + f.getName());
            }
        }
    }

    public static byte[] convertStreamToByte(InputStream inputStream) {
        byte[] result = null;
        try {
            byte[] buffer = new byte[1024];
            int len = 0;
            ByteArrayOutputStream bos = new ByteArrayOutputStream();
            while ((len = inputStream.read(buffer)) != -1) {
                bos.write(buffer, 0, len);
            }
            bos.close();
            result = bos.toByteArray();
        } catch (Exception e) {
            LogUtil.error(e);
        }
        return result;
    }

    public static void merageFile(List<File> fileList,String merageFilePath) {
        try{
            File merageFile = new File(merageFilePath);
            if (!merageFile.exists()) {
                BufferedOutputStream destOutputStream = new BufferedOutputStream(new FileOutputStream(merageFilePath));
                for (File file : fileList) {
                    byte[] fileBuffer = new byte[1024 * 1024 * 5];//文件读写缓存
                    int readBytesLength = 0; //每次读取字节数
                    BufferedInputStream sourceInputStream = new BufferedInputStream(new FileInputStream(file));
                    while ((readBytesLength = sourceInputStream.read(fileBuffer)) != -1) {
                        destOutputStream.write(fileBuffer, 0, readBytesLength);
                    }
                    sourceInputStream.close();
                }
                destOutputStream.flush();
                destOutputStream.close();
            }
        }catch (Exception e){
            LogUtil.error(e);
        }
    }

    public static String readFileContent(String fileName) {
        String fileContent = "";
        FileInputStream fis = null;
        InputStreamReader isr = null;
        try {
            fis = new FileInputStream(fileName);
            isr = new InputStreamReader(fis, "UTF-8");
            BufferedReader br = new BufferedReader(isr);
            String line = null;
            while ((line = br.readLine()) != null) {
                fileContent += line;
            }
        } catch (Exception e) {
            LogUtil.error(e);
        } finally {
            try {
                if (isr != null) {
                    isr.close();
                }
                if (fis != null) {
                    fis.close();
                }
            } catch (Exception e) {

            }
        }
        return fileContent;
    }

    public static String readFileContentGBK(String fileName) {
        String fileContent = "";
        FileInputStream fis = null;
        InputStreamReader isr = null;
        try {
            fis = new FileInputStream(fileName);
            isr = new InputStreamReader(fis,"GBK");
            BufferedReader br = new BufferedReader(isr);
            String line = null;
            while ((line = br.readLine()) != null) {
                fileContent += line;
            }
        } catch (Exception e) {
            LogUtil.error(e);
        } finally {
            try {
                if (isr != null) {
                    isr.close();
                }
                if (fis != null) {
                    fis.close();
                }
            } catch (Exception e) {

            }
        }
        return fileContent;
    }

    public static String readFileContentKeepLine(String fileName) {
        StringBuilder fileContent = new StringBuilder();
        FileInputStream fis = null;
        InputStreamReader isr = null;
        try {
            fis = new FileInputStream(fileName);
            isr = new InputStreamReader(fis, "UTF-8");
            BufferedReader br = new BufferedReader(isr);
            String line = null;
            while ((line = br.readLine()) != null) {
                fileContent.append(line + System.getProperty("line.separator"));
            }
        } catch (Exception e) {
            LogUtil.error(e);
        } finally {
            try {
                if (isr != null) {
                    isr.close();
                }
                if (fis != null) {
                    fis.close();
                }
            } catch (Exception e) {

            }
        }
        return fileContent.toString();
    }

    public static String readLastLine(String path, int numLastLineToRead) {
        File file = new File(path);
        StringBuilder builder = new StringBuilder();
        List<String> result = new ArrayList();
        try (ReversedLinesFileReader reader = new ReversedLinesFileReader(file, Charset.defaultCharset())) {
            String line = "";
            while ((line = reader.readLine()) != null && result.size() < numLastLineToRead) {
                result.add(line);
            }
            //倒叙遍历
            Collections.reverse(result);
        } catch (IOException e) {
            LogUtil.error(e);
        }
        for (String s : result) {
            builder.append(s + "</br>");
        }
        return builder.toString();
    }

    public static void writeFile(String fileName, String content, boolean append) {
        FileOutputStream fos = null;
        try {
            fos = new FileOutputStream(fileName, append);
            fos.write(content.getBytes("UTF-8"));
            fos.close();
        } catch (IOException e) {
            LogUtil.error(e);
        } finally {
            try {
                if (fos != null) {
                    fos.close();
                }
            } catch (Exception e) {

            }
        }
    }

    public static String getCreationTime(File file) {
        if (file == null) {
            return null;
        }
        BasicFileAttributes attr = null;
        try {
            Path path =  file.toPath();
            attr = Files.readAttributes(path, BasicFileAttributes.class);
        } catch (IOException e) {
            e.printStackTrace();
        }
        Instant instant = attr.creationTime().toInstant();
        String format = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss").withZone(ZoneId.systemDefault()).format(instant);
        return format;
    }

    public static String getLastModifyTime(File file) {
        if (file == null) {
            return null;
        }
        BasicFileAttributes attr = null;
        try {
            Path path =  file.toPath();
            attr = Files.readAttributes(path, BasicFileAttributes.class);
        } catch (IOException e) {
            e.printStackTrace();
        }
        Instant instant = attr.lastModifiedTime().toInstant();
        String format = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss").withZone(ZoneId.systemDefault()).format(instant);
        return format;
    }

    public static long getTotalSize(File file) {
        if (file.isFile()) {
            return file.length();
        }
        File[] list = file.listFiles();
        long total = 0;
        if (list != null) {
            for (File f : list) {
                total += getTotalSize(f);
            }
        }
        return total;
    }
}
